﻿using System;
using System.Linq;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using WebApiClientCore;
using WebApiClientCore.Attributes;

namespace Yyd.ExternalService.CustomerMarking.Attributes
{
    public class CrmJsonReturnAttribute : JsonReturnAttribute
    {
        /// <summary>
        /// 忽略的异常消息
        /// </summary>
        public string[] IgnoreExceptionMsgs { get; set; } = Array.Empty<string>();

        public override async Task SetResultAsync(ApiResponseContext context)
        {
            // var responseMessage = await context.HttpContext.ResponseMessage?.Content?.ReadAsStringAsync();

            var resultType = !context.ApiAction.Return.DataType.IsRawHttpResponseMessage
                ? typeof(BaseResult<>).MakeGenericType(context.ApiAction.Return.DataType.Type)
                : typeof(NullBaseResult);

            var result = (BaseApiResult) await context.JsonDeserializeAsync(resultType).ConfigureAwait(false);

            if (result == null)
            {
                throw new Exception(
                    $"接口  {context.HttpContext.RequestMessage.RequestUri.AbsolutePath} 异常的返回值 {context.HttpContext.ResponseMessage?.Content?.ReadAsStringAsync()}");
            }

            if (!result.Success && !IgnoreExceptionMsgs.Contains(result.Msg))
            {
                throw new Exception($"接口 {result.Api} 请求失败：" + result.Msg);
            }

            context.Result = result.GetData();
        }


        /// <summary>
        /// 
        /// </summary>
        public abstract class BaseApiResult
        {
            /// <summary>
            /// 
            /// </summary>
            [JsonPropertyName("api")]
            public string Api { get; set; }

            /// <summary>
            /// 
            /// </summary>
            [JsonPropertyName("code")]
            public string Code { get; set; }

            /// <summary>
            /// 
            /// </summary>
            [JsonIgnore]
            public bool Success => Code == "0000" || Code == "0000000";

            /// <summary>
            /// 
            /// </summary>
            [JsonPropertyName("msg")]
            public string Msg { get; set; }

            /// <summary>
            /// 
            /// </summary>
            [JsonPropertyName("sid")]
            public string Sid { get; set; }

            /// <summary>
            /// 
            /// </summary>
            [JsonPropertyName("cid")]
            public string Cid { get; set; }

            /// <summary>
            /// 
            /// </summary>
            [JsonPropertyName("timestamp")]
            public long Timestamp { get; set; }

            /// <summary>
            /// 
            /// </summary>
            /// <returns></returns>
            public abstract object GetData();
        }


        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TData"></typeparam>
        public class BaseResult<TData> : BaseApiResult
        {

            /// <summary>
            /// 
            /// </summary>
            [JsonPropertyName("data")]
            public TData Data { get; set; }

            /// <summary>
            /// 
            /// </summary>
            /// <returns></returns>
            public override object GetData()
            {
                return Data;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public class NullBaseResult : BaseApiResult
        {
            /// <summary>
            /// 
            /// </summary>
            /// <returns></returns>
            public override object GetData()
            {
                return null;
            }
        }
    }
}
